home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-04-18 | 16.5 KB | 498 lines | [TEXT/MMCC] |
- /* Multi-Pane Dialog (MPD)
- * By Norman Franke
- */
-
- // Required headers.
- #ifndef __DIALOGS__
- #include <Dialogs.h>
- #endif
-
- #ifndef __LISTS__
- #include <Lists.h>
- #endif
-
- #ifndef __FONTS__
- #include <Fonts.h>
- #endif
-
- #ifndef __TEXTUTILS__
- #include <TextUtils.h>
- #endif
-
-
- /********************************************************************************
- *
- * Multi-Pane Dialog Constants
- *
- ********************************************************************************/
-
- // Return codes
- #define kNotHandled 0
- #define kHandled -1
- #define keNullData 1
- #define keBadPane 2
- #define keBadItem 3
- #define keWrongSize 4
-
- // Standard item numbers in dialogs.
- #define kBOk 1
- #define kBCancel 2
- #define kBRevert 3
- #define kBFactory 4
- #define kIconBox 5
- #define kKeyStrings 6
- #define kLine 7
-
- // Action messages for use in the various Action Procedures.
- #define kR2TAction 0
- #define kP2TAction 1
- #define kT2PAction 2
- #define kT2RAction 3
- #define kCalcAction 4
- #define kInitAction 5
- #define kClickAction 6
- #define kValidateAction 7
-
- // Types of Action Procedures used in InstallAction and RemoveAction.
- #define kItemAction 1
- #define kEditAction 2
- #define kGroupAction 3
- #define kDefAction 4
-
- // Arrow Keys on the keyboard.
- #define kLeftArrow 0x1c
- #define kRightArrow 0x1d
- #define kUpArrow 0x1e
- #define kDownArrow 0x1f
-
- // Special resource types used here.
- #define kDTL 'DTL#'
- #define kGROUP 'DGRP'
-
- // Resources for the List pseudo-CDEF.
- #define rIconDef 130
-
- /********************************************************************************
- *
- * Multi-Pane Dialog Data Types and Universal Procedure Pointers
- *
- ********************************************************************************/
-
- // Radio Group linked list.
- typedef struct RadioGroup {
- struct RadioGroup *next;
- short pane;
- short num;
- short items[1];
- } RadioGroup, *RadioGroupPtr;
-
- #if USESROUTINEDESCRIPTORS
- #define kCallConvention kPascalStackBased
- #endif
-
- // Types for the Action procedures.
- typedef short ClickActionProc(short, DialogPtr, short, short);
- typedef ClickActionProc *ClickActionPtr;
-
- #if USESROUTINEDESCRIPTORS
- enum {
- kClickProcInfo = kCallConvention |
- STACK_ROUTINE_PARAMETER(1, sizeof(short)) |
- STACK_ROUTINE_PARAMETER(2, sizeof(DialogPtr)) |
- STACK_ROUTINE_PARAMETER(3, sizeof(short)) |
- STACK_ROUTINE_PARAMETER(4, sizeof(short)) |
- RESULT_SIZE(sizeof(short))
- };
-
- typedef UniversalProcPtr ClickActionUPP;
-
- #define CallClickActionProc(userRoutine, a1, a2, a3, a4) \
- CallUniversalProc((UniversalProcPtr)(userRoutine), kClickProcInfo, a1, a2, a3, a4)
- #define NewClickActionProc(userRoutine) \
- (ClickActionUPP) NewRoutineDescriptor((ProcPtr)(userRoutine), kClickProcInfo, GetCurrentISA())
- #else
- typedef ClickActionPtr ClickActionUPP;
-
- #define CallClickActionProc(userRoutine, a1, a2, a3, a4) \
- (*(userRoutine))(a1, a2, a3, a4)
- #define NewClickActionProc(userRoutine) (ClickActionUPP)(userRoutine)
- #endif
-
- typedef short EditActionProc(short, Ptr, Handle, short, short);
- typedef EditActionProc *EditActionPtr;
-
- #if USESROUTINEDESCRIPTORS
- enum {
- kEditProcInfo = kCallConvention |
- STACK_ROUTINE_PARAMETER(1, sizeof(short)) |
- STACK_ROUTINE_PARAMETER(2, sizeof(Ptr)) |
- STACK_ROUTINE_PARAMETER(3, sizeof(Handle)) |
- STACK_ROUTINE_PARAMETER(4, sizeof(short)) |
- STACK_ROUTINE_PARAMETER(5, sizeof(short)) |
- RESULT_SIZE(sizeof(short))
- };
-
- typedef UniversalProcPtr EditActionUPP;
-
- #define CallEditActionProc(userRoutine, a1, a2, a3, a4, a5) \
- CallUniversalProc((UniversalProcPtr)(userRoutine), kEditProcInfo, a1, a2, a3, a4, a5)
- #define NewEditActionProc(userRoutine) \
- (EditActionUPP) NewRoutineDescriptor((ProcPtr)(userRoutine), kEditProcInfo, GetCurrentISA())
- #else
- typedef EditActionPtr EditActionUPP;
-
- #define CallEditActionProc(userRoutine, a1, a2, a3, a4, a5) \
- (*(userRoutine))(a1, a2, a3, a4, a5)
- #define NewEditActionProc(userRoutine) (EditActionUPP)(userRoutine)
- #endif
-
- typedef short GroupActionProc(short, RadioGroupPtr, Handle, DialogPtr, Ptr, short, short);
- typedef GroupActionProc *GroupActionPtr;
-
- #if USESROUTINEDESCRIPTORS
- enum {
- kGroupProcInfo = kCallConvention |
- STACK_ROUTINE_PARAMETER(1, sizeof(short)) |
- STACK_ROUTINE_PARAMETER(2, sizeof(RadioGroupPtr)) |
- STACK_ROUTINE_PARAMETER(3, sizeof(Handle)) |
- STACK_ROUTINE_PARAMETER(4, sizeof(DialogPtr)) |
- STACK_ROUTINE_PARAMETER(5, sizeof(Ptr)) |
- STACK_ROUTINE_PARAMETER(6, sizeof(short)) |
- STACK_ROUTINE_PARAMETER(7, sizeof(short)) |
- RESULT_SIZE(sizeof(short))
- };
-
- typedef UniversalProcPtr GroupActionUPP;
-
- #define CallGroupActionProc(userRoutine, a1, a2, a3, a4, a5, a6, a7) \
- CallUniversalProc((UniversalProcPtr)(userRoutine), kGroupProcInfo, a1, a2, a3, a4, a5, a6, a7)
- #define NewGroupActionProc(userRoutine) \
- (GroupActionUPP) NewRoutineDescriptor((ProcPtr)(userRoutine), kGroupProcInfo, GetCurrentISA())
- #else
- typedef GroupActionPtr GroupActionUPP;
-
- #define CallGroupActionProc(userRoutine, a1, a2, a3, a4, a5, a6, a7) \
- (*(userRoutine))(a1, a2, a3, a4, a5, a6, a7)
- #define NewGroupActionProc(userRoutine) (GroupActionUPP)(userRoutine)
- #endif
-
- typedef void DefActionProc(Ptr, short, short, short, short);
- typedef DefActionProc *DefActionPtr;
-
- #if USESROUTINEDESCRIPTORS
- enum {
- kDefProcInfo = kCallConvention |
- STACK_ROUTINE_PARAMETER(1, sizeof(Ptr)) |
- STACK_ROUTINE_PARAMETER(2, sizeof(short)) |
- STACK_ROUTINE_PARAMETER(3, sizeof(short)) |
- STACK_ROUTINE_PARAMETER(4, sizeof(short)) |
- STACK_ROUTINE_PARAMETER(5, sizeof(short))
- };
-
- typedef UniversalProcPtr DefActionUPP;
-
- #define CallDefActionProc(userRoutine, a1, a2, a3, a4, a5) \
- CallUniversalProc((UniversalProcPtr)(userRoutine), kDefProcInfo, a1, a2, a3, a4, a5)
- #define NewDefActionProc(userRoutine) \
- (DefActionUPP) NewRoutineDescriptor((ProcPtr)(userRoutine), kDefProcInfo, GetCurrentISA())
- #else
- typedef DefActionPtr DefActionUPP;
-
- #define CallDefActionProc(userRoutine, a1, a2, a3, a4, a5) (*(userRoutine))(a1, a2, a3, a4, a5)
- #define NewDefActionProc(userRoutine) (DefActionUPP)(userRoutine)
- #endif
-
- // All the state used by the multi-pane dialog code.
- typedef struct MPDRec {
- // Number of panes in the dialog
- short numPanes;
- // Current pane being displayed
- short currentPane;
- // Item number of first item in the panes
- short baseItems;
- // List of IDs for the pane's DITLs
- short *paneIDs;
- // Whether the Revert button should be enabled
- short paneDirty;
- // Linked list of Radio Groups
- RadioGroupPtr radio;
- // Actual and temporary storage for dialog values
- Handle theData, tmpData;
- // List of icon suites
- Handle *IconHandles;
- // List Manager list for the icon list
- ListHandle theList;
- // Action Procedures
- ClickActionUPP ClickAction;
- EditActionUPP EditAction;
- GroupActionUPP GroupAction;
- DefActionUPP DefAction;
- } MPDRec, *MPDPtr, **MPDHdl;
-
- /********************************************************************************
- *
- * Main Multi-Pane Dialog Routines
- *
- ********************************************************************************/
-
- /* Open a new MPD.
- *
- * First parameter is the resource ID of the DLOG and DTL# for the dialog.
- * DTL#'s list the name and ID for each pane.
- * The ID is also for the icon group and optional DGRP resource.
- * Second through fifth parameters allow custom procedure for handling:
- * - Code to set factory defaults,
- * - Actions when items are clicked on,
- * - How TextEdit fields are treated, and
- * - How Radio Groups are handled.
- * Last parameter is the storage for the MPD data.
- * Passing a pointer to NULL will create a new one based on the DITLs.
- */
- DialogPtr OpenMPDialog(short resID, DefActionUPP defAction, ClickActionUPP clickProc,
- EditActionUPP editAction, GroupActionUPP groupAction, Handle *theData);
-
- /* Remove a MPD,
- * and deallocates all storage, exept the data handle.
- */
- void CloseMPDialog(DialogPtr *dlog);
-
- /* Handle an event in the MPD.
- *
- * Returns kNotHandled if the event is not for the MPD.
- * The DialogPtr is set to NULL if the event caused the MPD to close.
- * (CloseMPDialog is called in this case.)
- */
- short DoMPDialogEvent(DialogPtr *dlog, EventRecord *theEvent);
-
- /* Determine if the current pane has more than a single edit field.
- * Returns true if so.
- */
- Boolean MultipleEditFields(DialogPtr dlog);
-
- /* Installs an Action Procedure.
- *
- * First parameter is the type, second is the DialogPtr of the MPD,
- * third is the ProcPtr to the Action procedure.
- * If NULL is passed for the ProcPtr, the Action procedure is reset to
- * the default action.
- */
- short InstallAction(short aType, DialogPtr dlog, UniversalProcPtr actionProc);
-
- /* Remove an Action Procedure.
- *
- * Calls InstallAction with a NULL actionProc.
- */
- short RemoveAction(short aType, DialogPtr dlog);
-
- /********************************************************************************
- *
- * Multi-Pane Dialog Data Access Routines
- *
- ********************************************************************************/
-
- /* Retrieve a MPD item value.
- *
- * Given a MPD data handle, pane ID and item it will retrieve the
- * data into the passed pointer.
- * It verifies that the length is correct, and a valid pane and item were passed.
- */
- short GetMPDItem(Handle theData, short pane, short item, Ptr ptr, short len);
-
- /* Store a MPD item value.
- *
- * Given a MPD data handle, pane ID and item it will store the
- * data from the passed pointer into the MPD data handle.
- * It verifies that the length is correct, and a valid pane and item were passed.
- */
- short SetMPDItem(Handle theData, short pane, short item, Ptr ptr, short len);
-
- /********************************************************************************
- *
- * Internal Multi-Pane Dialog Routines
- *
- ********************************************************************************/
-
- /* Display a pane.
- *
- * Removes the old pane and installes the new in the dialog.
- */
- void InstallDITL(DialogPtr dlog, short pane);
-
- /* Create a new empty MPD data handle.
- *
- * The first part of the handle is a series of long offsets into
- * the handle where the individual pane values are stored, zero terminated.
- * Controls, Check boxes and non-groups Radio Buttons are stored as shorts.
- * Default action is to store TextEdit fields as Str255's.
- * A single short is allocated for a Radio Group.
- * The end of the item list per pane is zero terminated.
- */
- Handle MPDTemplateFromDITL(MPDHdl dataH);
-
- /* Create a Radio Group.
- *
- * First parameter is the MPD, second is the pane ID,
- * third is a list of item numbers for the group (numbering local to the DITL),
- * last is the number of items in the array/group.
- */
- short CreateMPDRadioGroup(DialogPtr dlog, short pane, short *itemList, short itemNum);
-
- /* Create Radio Groups for a pane.
- *
- * First parameter is the MPD, second is the pane ID.
- * This reads a DGRP resource to get the Radio Groups for a pane.
- * Most of the work is done in CreateMPDRadioGroup.
- */
- void CreateRadioGroups(DialogPtr dlog, short pane);
-
- /* Sets MPD controls on the display to their factory settings.
- *
- * Given the MPD and the pane, it sets the default values for the controls on that pane.
- */
- void SetFactoryDefault(DialogPtr dlog, short pane);
-
- /* Toggle items in a Radio Group.
- *
- * Given the MPD, the specific Radio and a DITL-local number,
- * make sure it's the only Radio Button set in the group.
- */
- void ToggleGroup(DialogPtr dlog, RadioGroupPtr group, short item);
-
- /* Calculates the size the Radio Button needs in the MPD data handle.
- *
- * If the radio button is a member of a Radio Group it returns zero,
- * since radio groups are stored separately.
- * Otherwise it returns sizeof(short).
- * It is passed the first Radio Group and the pane and item of the control.
- */
- short GetRadioMPDSize(RadioGroupPtr radio, short pane, short item);
-
- /********************************************************************************
- *
- * Internal Multi-Pane Dialog Action Procedures
- *
- ********************************************************************************/
-
- /* MPD Action Procedure.
- *
- * Given the MPD and pane, and
- * depending on the value of the second argument it will:
- * - Create a working copy of the MPD data handle for use,
- * - Call P2TMPDAction to save the controls,
- * - Call T2PMPDAction to set the controls,
- * - Save the temporary results of the MPD into the MPD data handle,
- * - Call P2TMPDAction or T2PMPDAction.
- */
- short HandleMPDAction(DialogPtr dlog, short message, short pane);
-
- /* Transfer the MPD controls as displayed into the temporary MPD data handle.
- *
- * When the user switches panes, the values need to be saved.
- * It calls the Action Procedure for Radio Button and TextEdit fields.
- * If a radio button is not in a group, it is treated like a check box.
- */
- short P2TMPDAction(DialogPtr dlog, short pane);
-
- /* Transfer the values from the temporary MPD data handle to the display.
- *
- * When the user switches panes, the values need to be restored.
- * It calls the Action Procedure for Radio Button and TextEdit fields.
- * If a radio button is not in a group, it is treated like a check box.
- */
- short T2PMPDAction(DialogPtr dlog, short pane);
-
- /* Handler for when a user clicks on a Radio Button.
- *
- * Returns kNotHandled if the radio button is not in a Radio Group.
- * It gets passed the MPD and the DITL local item number hit.
- */
- short HandleRadioGroup(DialogPtr dlog, short item);
-
- /* Do Radio Group Action Procedure.
- *
- * Calls the Group Action Procedure for each Radio Group.
- * For kP2TAction and kT2PAction dlog is the MPD,
- * for kCalcAction and kInitAction it is the MPDHdl.
- */
- short DoGroupAction(short mType, DialogPtr dlog, Ptr hPtr, short pane, short *item);
-
- /********************************************************************************
- *
- * Default Action Procedures
- *
- ********************************************************************************/
-
- /* Set default values for a pane.
- *
- * Given the data pointer, length of item's storage, type, pane and DITL local item,
- * set the defaults for all the items on that pane.
- * Default action sets everything to zero.
- */
- void DefaultAction(Ptr theData, short len, short iType, short pane, short item);
-
- /* TextEdit Action Procedure.
- *
- * Depending on the value of the first argument it will:
- * - Save the value of a TextEdit field, which is the actual text as a pascal string.
- * - Set the value of a TextEdit field.
- * - Return the amount of item storage needed for a TextEdit (256).
- * - Initialize the TextEdit record.
- * Second parameter is the ControlHandle for the control being processed,
- * followed by the pane and item number of the control.
- */
- short DefaultEditAction(short mType, Ptr hPtr, Handle iHandle, short pane, short item);
-
- /* Action Procedure when something is clicked or validated.
- *
- * The first parameter specifies the message type:
- * kInitAction, kValidateAction or kClickAction
- * For clicking and initialization:
- * Nothing happens for buttons and controls,
- * Radio groups are handled in HandleRadioGroup or are toggled if it can't, and
- * Check boxes are simply toggled.
- * Validation always succeeds.
- */
- short DefaultClickAction(short mType, DialogPtr dlog, short pane, short item);
-
- /* Radio Group Action Procedure.
- *
- * Depending on the value of the first argument it will:
- * - Save the value of a Radio Group, which is the index of the control in the group.
- * - Set the value of a Radio Group.
- * - Return the amount of item storage needed for a Radio Group.
- * - Initialize the value of the Radio Group to 1.
- * The second argument is the Radio Group being processed, third is the MPDHdl,
- * fourth the DialogPtr, fifth a pointer to the storage pointer (which is updated
- * here), lastly the pane and item number of the control in the group.
- */
- short DefaultGroupAction(short mType, RadioGroupPtr group, Handle H, DialogPtr dlog,
- Ptr hPtr, short pane, short item);
-
-
- /* Useful routines I use a lot.
- * By Norman Franke
- */
-
- // ******************** Gray Line
- pascal void DrawGray (DialogPtr theDialog, short theItem);
- void SetItemToGray(DialogPtr dlog, short item);
-
- // ******************** Command Key Equivalents
- pascal Boolean keyAltFilter(DialogPtr dlg, short theItem, short offset, EventRecord *event, short *item);
-
- // ******************** Menu
- void AbleDisItem(short menu, short item, short flag);
-
- // ******************** Grow Icon
- void MyDrawGrow(WindowPtr win);
-
- // ******************** Dialog & Window
- void HiliteItem(DialogPtr dlgPtr, short itemNo, short state);
- ControlHandle GetItemHandle(DialogPtr theDialog, short item);
- short GetDItemValue(DialogPtr dlgPtr, short itemNo);
- void AbleDItem(DialogPtr dlog, short item, short state);
- DialogPtr MyGetCenteredDialog(short id, DialogPtr storage, WindowPtr relatedWindow, WindowPtr behind);
-
- // ******************** Miscelaneous
- void Pstrcpy(Str255, ConstStr255Param);
-